package com.service;

import static com.def.GenericDef.E_XPPMCHK_INVALID_INPUT;
import static com.def.GenericDef.MLDP_PDA;
import static com.def.GenericDef.RETURN_CODE_OK;
import static com.def.GenericDef.RETURN_CODE_SET_ERROR;
import static com.def.GenericDef.RETURN_CODE_UNKNOWN;
import static com.def.GenericDef.RETURN_MESG_OK;
import static com.def.GenericDef.TRX_OUT;
import static com.def.GenericDef.T_XPPMCHK;
import static com.def.GenericDef._NORMAL;
import static com.def.GenericDef._YES;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.dao.IBisMItemDao;
import com.dao.IBisMLabelDao;
import com.dao.IRetPrdInfoDao;
import com.icim.service.ICIMBaseService;
import com.model.Bis_m_item;
import com.model.Bis_m_itemId;
import com.model.Bis_m_label;
import com.model.Bis_m_labelId;
import com.tx.Xppmchk.XppmchkI;
import com.tx.Xppmchk.XppmchkO;
import com.tx.Xppmchk.XppmchkOItem;
import com.util.GUIDGenerator;
import com.util.MqOpe;
import com.util.Util;

@Scope("prototype")
@Service("XppmchkService")
public class XppmchkService extends ICIMBaseService{
	private static Logger logger = Logger.getLogger(XppmchkService.class);
	private static String TX_NAME = T_XPPMCHK;

	private XppmchkI inTrx;
	private XppmchkO outTrx;
	private MqOpe mqOpe;

	private String gszMsgBuf = "";
	private Timestamp gEvtTimestamp;
	private Double gEvtTimeD;
	private String gEvtSeqID;

	@Autowired
	private IRetPrdInfoDao retPrdInfoDao;

	@Autowired
	private IBisMLabelDao bisMLabelDao;
	@Autowired
	private IBisMItemDao bisMItemDao;

	public String subMainProc(String strInMsg) {
		long rtnCode = _NORMAL;

		String outMsg = null;
		gszMsgBuf = "";
		gEvtTimestamp = Util.getCurrentTimestamp();
		gEvtTimeD = Util.getDoubleTime();
		gEvtSeqID = GUIDGenerator.javaGUID();
		inTrx = new XppmchkI();
		outTrx = new XppmchkO();
		outTrx.setTrx_id(TX_NAME);
		outTrx.setType_id(TRX_OUT);
		outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));
		mqOpe = new MqOpe();

		try {
			inTrx = (XppmchkI) mqOpe.inStr2Obj(strInMsg, inTrx);
			logger.info("InTrx is " + strInMsg);

			rtnCode = subMainProc2(inTrx.getAct_flg().toCharArray()[0]);
			if (rtnCode != _NORMAL) {
				TransactionAspectSupport.currentTransactionStatus()
						.setRollbackOnly();
				outTrx.setRtn_code(String.valueOf(rtnCode));
				outTrx.setRtn_mesg(gszMsgBuf);
			} else {
				outTrx.setRtn_code(String.valueOf(RETURN_CODE_OK));
				outTrx.setRtn_mesg(RETURN_MESG_OK);
				retPrdInfoDao.flushCurSession();
			}
		} catch (Exception ex) {
			TransactionAspectSupport.currentTransactionStatus()
					.setRollbackOnly();
			outTrx.setRtn_mesg(ex.toString());
			outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
			logger.error(Util.stackTraceToString(ex));
		} finally {
			outMsg = mqOpe.obj2Str(outTrx);
			return outMsg;
		}
	}

	/**
	 * All move in logic
	 * 
	 * @return
	 */
	private long subMainProc2(char actionType) {
		long lRc = _NORMAL;

		switch (actionType) {
		case 'C': {
			lRc = getChkItemList();
			if (lRc != _NORMAL) {
				return lRc;
			}
			break;
		}
		case 'A': {
			lRc = addChkItem();
			if (lRc != _NORMAL) {
				return lRc;
			}
			break;
		}
		default: {
			gszMsgBuf = "Invalide type input: [" + actionType + "]";
			return E_XPPMCHK_INVALID_INPUT;
		}
		}

		return lRc;
	}

	/**
	 * Add one tool check item indo BIS_M_ITEM
	 * 
	 * @return
	 */
	private long addChkItem() {
		long rtnCode = _NORMAL;
		Bis_m_label bis_m_label = new Bis_m_label();
		Bis_m_labelId bis_m_labelId = new Bis_m_labelId();
		Bis_m_item bis_m_item = new Bis_m_item();
		Bis_m_itemId bis_m_itemId = new Bis_m_itemId();

		// Get Bis_m_label
		bis_m_labelId.setTool_id_fk(inTrx.getTool_id());
		bis_m_labelId.setRep_unit("T");
		bis_m_labelId.setData_pat(MLDP_PDA);
		bis_m_labelId.setMes_id_fk(inTrx.getChk_mes_id());
		bis_m_label = bisMLabelDao.get(bis_m_labelId);
		if (null == bis_m_label) {
			Bis_m_label bis_m_label_add = new Bis_m_label();
			bis_m_label_add.setId(bis_m_labelId);
			bis_m_label_add.setUnq_seq_id(gEvtSeqID);
			bis_m_label_add.setOpi_data_flg(_YES);
			bis_m_label_add.setEvt_user(inTrx.getEvt_user());
			bis_m_label_add.setEvt_timestamp(gEvtTimestamp);

			bisMLabelDao.save(bis_m_label_add);

			bis_m_itemId.setData_id("0");
		} else {
			bis_m_itemId.setData_id(String.valueOf(bisMItemDao
					.getMItemListByMLabel(bis_m_label).size() + 1));
		}

		// Set bis_m_itemId
		bis_m_itemId.setTool_id_fk(bis_m_labelId.getTool_id_fk());
		bis_m_itemId.setRep_unit_fk(bis_m_labelId.getRep_unit());
		bis_m_itemId.setData_id(bis_m_labelId.getData_pat());
		bis_m_itemId.setMes_id_fk(bis_m_labelId.getMes_id_fk());

		bis_m_item.setId(bis_m_itemId);
		bis_m_item.setUnq_seq_id(gEvtSeqID);
		bis_m_item.setData_dsc(inTrx.getChk_item());
		bis_m_item.setOpi_data_flg(_YES);
		bis_m_item.setL_spec(Double.valueOf(inTrx.getChk_l_spec()));
		bis_m_item.setU_spec(Double.valueOf(inTrx.getChk_u_spec()));

		bis_m_item.setEvt_usr(inTrx.getEvt_user());
		bis_m_item.setEvt_timestamp(gEvtTimestamp);

		bisMItemDao.save(bis_m_item);

		return _NORMAL;
	}

	/**
	 * Get check item list by MES_ID
	 * 
	 * @return
	 */
	private long getChkItemList() {
		long rtnCode = _NORMAL;
		List<Bis_m_item> bis_m_itemList = new ArrayList<Bis_m_item>();
		Bis_m_label bis_m_label = new Bis_m_label();
		Bis_m_labelId bis_m_labelId = new Bis_m_labelId();

		// Get Bis_m_label
		bis_m_labelId.setTool_id_fk(inTrx.getTool_id());
		bis_m_labelId.setRep_unit("T");
		bis_m_labelId.setData_pat(MLDP_PDA);
		bis_m_labelId.setMes_id_fk(inTrx.getChk_mes_id());
		bis_m_label = bisMLabelDao.get(bis_m_labelId);
		if (null != bis_m_label) {
			bis_m_itemList = bisMItemDao.getMItemListByMLabel(bis_m_label);
			if (!bis_m_itemList.isEmpty()) {
				List<XppmchkOItem> oaryItem = new ArrayList<XppmchkOItem>();
				for(Bis_m_item item : bis_m_itemList ){
					XppmchkOItem oItem = new XppmchkOItem();
					
					oItem.setTool_id(item.getId().getTool_id_fk());
					oItem.setChk_mes_id(item.getId().getMes_id_fk());
					oItem.setChk_item(item.getData_dsc());
					oItem.setChk_l_spec(item.getL_spec().toString());
					oItem.setChk_u_spec(item.getU_spec().toString());
					
					oaryItem.add(oItem);
				}
				outTrx.setOaryItem(oaryItem);
				outTrx.setRtn_cnt(oaryItem.size());
			}
		}
		
		//Not found label or item
		outTrx.setRtn_cnt(0);

		return _NORMAL;
	}
}
